﻿using BridgeWebSystemLib.Core.Util;
using Microsoft.AspNetCore.Server.IIS.Core;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace BridgeWebSystemLib.Core.Net
{
    public class HttpClientAccess : IHttpAccess
    {
        private static HttpClient _instans;

        public HttpClientAccess()
        {
            _instans = new HttpClient();
            _instans.DefaultRequestHeaders.Connection.Add("keep-alive");
        }

        public string Get(string url, IDictionary<string, string> paramArray = null)
        {
            if (paramArray != null)
                url = url + "?" + BuildParam(paramArray);
            var rep = _instans.GetAsync(url).Result;
            rep.EnsureSuccessStatusCode();
            if (rep.IsSuccessStatusCode)
            {
                return rep.Content.ReadAsStringAsync().Result;
            }
            else
            {
                return rep.StatusCode.ToString();
            }
        }

        public byte[] GetByte(string url, IDictionary<string, string> paramArray = null)
        {
            if (paramArray != null)
                url = url + "?" + BuildParam(paramArray);
            var rep = _instans.GetAsync(url).Result;
            rep.EnsureSuccessStatusCode();
            if (rep.IsSuccessStatusCode)
            {
                return rep.Content.ReadAsByteArrayAsync().Result;
            }
            else
            {
                throw new Exception(rep.StatusCode.ToString());
            }
        }

        public string GetByteCompression(string url, IDictionary<string, string> paramArray = null)
        {
            if (paramArray != null)
                url = url + "?" + BuildParam(paramArray);
            var rep = _instans.GetAsync(url).Result;
            rep.EnsureSuccessStatusCode();
            if (rep.IsSuccessStatusCode)
            {
                byte[] bytes = rep.Content.ReadAsByteArrayAsync().Result;
                return CompressionUtil.DeflateDecompress(bytes);
            }
            else
            {
                return rep.StatusCode.ToString();
            }
        }

        public string PostJson(string url, string content, AuthenticationHeaderValue headerValue = null)
        {
            if (content == null)
                content = "";
            HttpContent httpContent = new StringContent(content);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            httpContent.Headers.ContentType.CharSet = "utf-8";
            if (headerValue != null)
                _instans.DefaultRequestHeaders.Authorization = headerValue;
            
            var rep = _instans.PostAsync(url, httpContent).Result;
            rep.EnsureSuccessStatusCode();
            if (rep.IsSuccessStatusCode)
            {
                return rep.Content.ReadAsStringAsync().Result;
            }
            else
            {
                return rep.StatusCode.ToString();
            }
        }

        public async Task<string> PostJsonAsync(string url, string content, AuthenticationHeaderValue headerValue = null)
        {
            HttpContent httpContent = new StringContent(content);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            if(headerValue != null)
                _instans.DefaultRequestHeaders.Authorization = headerValue;
            var rep = _instans.PostAsync(url, httpContent).Result;
            rep.EnsureSuccessStatusCode();
            if (rep.IsSuccessStatusCode)
            {
                return await rep.Content.ReadAsStringAsync();
            }
            else
            {
                return rep.StatusCode.ToString();
            }
        }

        private static string BuildParam(IDictionary<string, string> paramArray, Encoding encode = null)
        {
            var parms = "";
            if (encode == null) 
                encode = Encoding.UTF8;
            if (paramArray != null && paramArray.Count > 0)
            {
                foreach (var item in paramArray)
                {
                    parms += string.Format("{0}={1}&", HttpUtility.UrlEncode(item.Key, encode), HttpUtility.UrlEncode(item.Value, encode));
                }
                if (parms != "")
                {
                    parms = parms.TrimEnd('&');
                }
            }
            return parms;
        }
    }
}
